/**
 * \file Graphe.cpp
 * \brief Tests unitaires de la classe ReseauAerien
 * \author Pierre-Marc Levasseur, Simon Rodier
 * \version 0.1
 * \date juillet 2014
 *
 *  Travail pratique numéro 3
 *
 */

#include<gtest/gtest.h>
#include"ReseauAerien.h"
#include<iostream>

using namespace std;
using namespace TP3;

TEST(ReseauAerien, chargerReseau_chargeCorrectementLeFichier)
{
	ReseauAerien r;

	ifstream f("ReseauAerien.txt", ios::in);

	r.chargerReseau(f);
}



TEST(ReseauAerien, operateurAssignation_laCopieEstProfonde)
{
	ReseauAerien rCopie;
	{
		ReseauAerien r;
		ifstream f("ReseauAerien.txt", ios::in);
		r.chargerReseau(f);
		rCopie = r;
	}
	ASSERT_TRUE(rCopie.getNomReseau()=="Air Canada");
}



class ReseauAerienTest : public ::testing::Test
{
public:
	ReseauAerienTest():r()
	{
		ifstream f("ReseauAerien.txt", ios::in);

		r.chargerReseau(f);
	}

	ReseauAerien r;
};
TEST_F(ReseauAerienTest, rechercheCheminDijkstra_cheminSize3)
{
	Chemin rep = r.rechercheCheminDijkstra("Quebec","Paris", true);
	cout<<"Chemin Dijkstra: "<<endl;
	for(unsigned int i = 0; i<rep.listeVilles.size();i++)
	{
		cout<<rep.listeVilles[i]<<endl;
	}
	cout<<"Cout: "<<rep.coutTotal<<endl;
	cout<<"Duree: "<<rep.dureeTotale<<endl;
	cout<<"NS: "<<rep.nsTotal<<endl;
	cout<<"Réussi: "<<rep.reussi<<endl;
	ASSERT_TRUE(rep.listeVilles.size() == 3);
}

TEST_F(ReseauAerienTest, rechercheCheminDijkstra_sommetsAdjacentsEtTrajetDirectEstLePlusCourt_cheminSize2)
{
	Chemin rep = r.rechercheCheminDijkstra("Quebec","Montreal",true);
	ASSERT_TRUE(rep.listeVilles.size()==2);
}

TEST_F(ReseauAerienTest, rechercheCheminDijkstra_aucunCheminVilleIsolee_retourneFalse)
{
	Chemin rep = r.rechercheCheminDijkstra("Quebec", "Singapour", false);
	ASSERT_FALSE(rep.reussi);
}

TEST_F(ReseauAerienTest, rechercheCheminDijkstra_aucunCheminVillePasIsolee_retourneFalse)
{
	Chemin rep = r.rechercheCheminDijkstra("Vancouver", "Chicago", false);
	ASSERT_FALSE(rep.reussi);
}

TEST_F(ReseauAerienTest, rechercheCheminDijkstra_villePasDansReseau_logicError)
{
	ASSERT_THROW(Chemin rep = r.rechercheCheminDijkstra("Quebec", "Patate", true), logic_error);
	ASSERT_THROW(Chemin rep2 = r.rechercheCheminDijkstra("Patate", "Quebec", true), logic_error);

}

TEST_F(ReseauAerienTest, bellManFord_sommetsAdjacentsEtTrajetDirectEstLePlusCourt_cheminSize2)
{
	Chemin rep = r.bellManFord("Quebec", "Montreal", 3);
	cout<<"Chemin Bellman Ford: size ("<<rep.listeVilles.size()<<")"<<endl;
	for(unsigned int i = 0; i<rep.listeVilles.size(); i++)
	{
		cout<<rep.listeVilles[i]<<endl;
	}
	cout<<"Cout: "<<rep.coutTotal<<endl;
	cout<<"Duree: "<<rep.dureeTotale<<endl;
	cout<<"Niv Sec: "<<rep.nsTotal<<endl;

	ASSERT_TRUE(rep.listeVilles.size()==2);
}

TEST_F(ReseauAerienTest, bellManFord_cheminSize3)
{
	Chemin rep = r.bellManFord("Quebec", "Paris", 3);
	cout<<"Chemin Bellman Ford: size ("<<rep.listeVilles.size()<<")"<<endl;
	for(unsigned int i = 0; i<rep.listeVilles.size(); i++)
	{
		cout<<rep.listeVilles[i]<<endl;
	}
	cout<<"Cout: "<<rep.coutTotal<<endl;
	cout<<"Duree: "<<rep.dureeTotale<<endl;
	cout<<"Niv Sec: "<<rep.nsTotal<<endl;

	ASSERT_TRUE(rep.listeVilles.size()==3);
}

TEST_F(ReseauAerienTest, bellManFord_villePasDansReseau_logicError)
{
	ASSERT_THROW(Chemin rep = r.bellManFord("Quebec", "Patate", 1), logic_error);
	ASSERT_THROW(Chemin rep2 = r.bellManFord("Patate", "Quebec", 3), logic_error);
}

TEST_F(ReseauAerienTest, bellManFord_cheminImpossibleVilleIsolee_logicError)
{
	ASSERT_FALSE(r.bellManFord("Quebec", "Singapour", 1).reussi);
}

TEST_F(ReseauAerienTest, bellManFord_cheminImpossibleVillePasIsolee_logicError)
{
	ASSERT_FALSE(r.bellManFord("Vancouver", "Chicago", 1).reussi);
}

//TEST_F(ReseauAerienTest, sauvegarderReseau_leReseauEstSauvegarde)
//{
//	ofstream fichier("reseauOutputTest.txt", std::ofstream::out);
//	r.sauvegarderReseau(fichier);
//	fichier.close();
//}

TEST_F(ReseauAerienTest, sauvegarderReseau_fichierPasOuvert_lanceLogicError)
{
	ofstream fichier("reseauOutputTest.txt", std::ofstream::out);
	fichier.close();
	ASSERT_THROW(r.sauvegarderReseau(fichier), logic_error);
}

TEST_F(ReseauAerienTest, rechercheCheminLargeur_chercheUnCheminEntreDeuxVilles_renvoieUneBonneReponse)
{
	vector<string> chemin;
	chemin = r.rechercheCheminLargeur("Quebec", "Bogota");

	cout << endl << "Chemin entre Québec et Bogota : " << endl;
	for(size_t i = 0; i < chemin.size(); i++)
		cout << chemin[i] << endl;

	cout << endl;

	ASSERT_EQ(4, chemin.size());
}

TEST_F(ReseauAerienTest,constructeurCopie_laCopieEstProfonde)
{
	ReseauAerien rCopie(r);
	r.viderReseau();
	ASSERT_TRUE(rCopie.getNomReseau()=="Air Canada");
}

TEST_F(ReseauAerienTest, rechercheCheminLargeur_chercheUnCheminEntreDeuxVilles_renvoieUneBonneReponse2)
{
	vector<string> chemin;
	chemin = r.rechercheCheminLargeur("Paris", "Tokyo");

	cout << endl << "Chemin entre Paris et Tokyo : " << endl;
	for(size_t i = 0; i < chemin.size(); i++)
		cout << chemin[i] << endl;

	cout << endl;

	ASSERT_EQ(4, chemin.size());
}

TEST_F(ReseauAerienTest, rechercheCheminLargeur_chercheUnCheminEntreDeuxVillesNonConnecte_renvoieUnVectorVide)
{
	vector<string> chemin;
	chemin = r.rechercheCheminLargeur("Vancouver", "Chicago");

	ASSERT_EQ(0, chemin.size());
}

TEST_F(ReseauAerienTest, rechercheCheminLargeur_chercheUnCheminEntreDeuxVillesNonConnecte_renvoieUnVectorVide2)
{
	vector<string> chemin;
	chemin = r.rechercheCheminLargeur("Vancouver", "Singapour");

	ASSERT_EQ(0, chemin.size());
}

TEST_F(ReseauAerienTest, viderReseau_leReseauEstVide)
{
	r.viderReseau();
	ASSERT_TRUE(r.getNomReseau()=="");
	ASSERT_TRUE(r.getTailleReseau()==0);
}

TEST_F(ReseauAerienTest, getTailleReseau_leNomEstBon)
{
	ASSERT_TRUE(r.getTailleReseau()==17);
}

TEST_F(ReseauAerienTest, getNomReseau_laTailleEstBonne)
{
	ASSERT_TRUE(r.getNomReseau()=="Air Canada");
}

//TEST_F(ReseauAerienTest, operateurAffichage)
//{
//	cout<<r;
//}

TEST_F(ReseauAerienTest, algorithmeAstar_chercheUnCheminEntreDeuxVilles_renvoieUneBonneReponse)
{
	Chemin ch = r.algorithmeAstar("Quebec", "Bogota", true);

	ASSERT_TRUE(ch.reussi);
	cout << endl << "Chemin entre Québec et Bogota : " << endl;
	for(size_t i = 0; i < ch.listeVilles.size(); i++)
		cout << ch.listeVilles[i] << endl;
	cout << "Coût total : " << ch.coutTotal << endl;
	cout << "Durée total : " << ch.dureeTotale << endl;
	cout << "Niveau de sécurité total : " << ch.nsTotal << endl;
	cout << endl;

}

TEST_F(ReseauAerienTest, algorithmeAstar_chercheUnCheminEntreDeuxVilles_renvoieUneBonneReponse2)
{
	Chemin ch = r.algorithmeAstar("Paris", "Auckland", false);

	ASSERT_TRUE(ch.reussi);
	cout << endl << "Chemin entre Paris et Auckland : " << endl;
	for(size_t i = 0; i < ch.listeVilles.size(); i++)
		cout << ch.listeVilles[i] << endl;
	cout << "Coût total : " << ch.coutTotal << endl;
	cout << "Durée total : " << ch.dureeTotale << endl;
	cout << "Niveau de sécurité total : " << ch.nsTotal << endl;
	cout << endl;
}

